﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Frogism.Core;
using Frogism.Core.WorkOut;
namespace Frogism.Domain {
  public class WorkoutDetail {
    private ActivityUser _user;
    public WorkoutDetail(ActivityUser user) {
      _user = user;
      Activities = _user.Activities.Where(a => a.ActivityType.ActivityGroup.Id == 1
          && a.ActivityDate >= StartDate
          && a.ActivityDate <= EndDate);
    }
    public DateTime StartDate { get { return _user.StartDate; } }
    public DateTime EndDate { get { return _user.EndDate; } }
    public decimal CaloriesBurned {
      get {
        return CaloriesBurnedAsOf(_user.EndDate);
      }
    }
    public decimal PredictedCaloriesBurned {
      get {
        return PredictedCaloriesBurnedAsOf(_user.EndDate);
      }
    }
    public int DaysIn(DateTime asOfDate) {
         return (asOfDate.Subtract(_user.StartDate).Days + 1);
    }
     public int DaysLeft(DateTime asOfDate) {
         return EndDate.Subtract(asOfDate).Days;
    }
     public decimal GoalCalories() {
       return GoalCalories(EndDate);
     }
    public decimal GoalCalories(DateTime asOfDate) {

      return DaysIn(asOfDate)* _user.DailyCalories;
    }

    public decimal TotalGoalCalories() {
      return GoalCalories(_user.EndDate);
    }

    public decimal CaloriesBurnedAsOf(DateTime dateTime) {
      //return Activities.Where(a2 => a2.Status == ActivityStatus.Complete && a2.ActivityDate <= dateTime).Sum(a => a.Units * a.ActivityType.Calories);
        decimal cals = 0;



        foreach (Activity a2 in Activities)
        {
            if (a2.Status == ActivityStatus.Complete && a2.ActivityDate <= dateTime)
            {
                cals += a2.Units * a2.ActivityType.Calories;
            }
        }

        return cals;
    }
    public decimal AverageDay {
      get {
        return CaloriesBurned / (decimal)DaysIn(DateTime.Now);
      }
    }
    public decimal AverageWeek {
      get {
        return CaloriesBurned / (decimal)DaysIn(DateTime.Now) * 7M;
      }
    }

    public decimal PredictedCaloriesBurnedAsOf(DateTime dateTime) {
      return Activities.Where(a2 => a2.Status != ActivityStatus.Failed && a2.ActivityDate <= dateTime).Sum(a => a.Calories);
    }
    public IEnumerable<IActivity> Activities { get; set; }

    public WorkoutDetail ThisWeek() {

      var newUser = new ActivityUser();
      newUser.Id = _user.Id;
      newUser.DailyCalories = _user.DailyCalories;
      newUser.Name = _user.Name;
      newUser.StartDate = DateTime.Now.StartOfWeek();
      newUser.EndDate = DateTime.Now.EndOfWeek();
      newUser.Activities = GetActivitiesDateRange(newUser.StartDate,newUser.EndDate).ToCollection();
      return new WorkoutDetail(newUser);
    }

    private IEnumerable<IActivity> GetActivitiesDateRange(DateTime startDate, DateTime endDate) {
      return _user.Activities.Where(a => a.ActivityDate >= startDate && a.ActivityDate <= endDate);
    }
    private IEnumerable<WorkoutTotal> _ByWeekTotals;
    public IEnumerable<WorkoutTotal> ByWeekTotals {
      get{
        if (_ByWeekTotals == null) {
          List<WorkoutTotal> tmpByWeekTotals = new List<WorkoutTotal>();

          DateTime startLoop = this._user.StartDate;

          while (startLoop <= DateTime.Now) {
            DateTime weekstart = startLoop.StartOfWeek();
            DateTime weekend = startLoop.EndOfWeek();
            IEnumerable<IActivity> alist = GetActivitiesDateRange(weekstart, weekend);

            WorkoutTotal total = new WorkoutTotal();
            total.DateStart = weekstart;
            total.BurnedCalories = alist.Where(a1=>a1.Status == ActivityStatus.Complete).Sum(a => a.Calories);
            total.GoalCalories = _user.DailyCalories * 7;

            tmpByWeekTotals.Add(total);
            startLoop = startLoop.AddDays(7);
          }
          _ByWeekTotals = tmpByWeekTotals.OrderByDescending(f => f.DateStart);
        }
        return _ByWeekTotals;
      }
      
    }
  }
}
